using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.Authorization;
using SqlsugarService.Application.AI.MES;
using System.Collections.Concurrent;
using System.Security.Claims;

namespace SqlsugarService.API.Hubs
{
    /// <summary>
    /// MES系统SignalR Hub
    /// 提供实时通信功能，包括：
    /// - 生产状态实时推送
    /// - 设备状态监控
    /// - 异常告警通知
    /// - AI助手实时对话
    /// - 工作流程协作
    /// </summary>
    public class MESHub : Hub
    {
        private readonly ILogger<MESHub> _logger;
        private readonly IMESToolService _mesToolService;
        
        // 用户连接管理
        private static readonly ConcurrentDictionary<string, UserConnection> _connections = new();
        
        // 用户组管理（按部门、角色等分组）
        private static readonly ConcurrentDictionary<string, HashSet<string>> _groups = new();

        public MESHub(ILogger<MESHub> logger, IMESToolService mesToolService)
        {
            _logger = logger;
            _mesToolService = mesToolService;
        }

        #region 连接管理

        /// <summary>
        /// 客户端连接时调用
        /// </summary>
        public override async Task OnConnectedAsync()
        {
            var connectionId = Context.ConnectionId;
            var userId = GetUserId();
            var userRole = GetUserRole();
            var department = GetUserDepartment();

            _logger.LogInformation("用户连接: {UserId}, 连接ID: {ConnectionId}", userId, connectionId);

            // 记录用户连接信息
            _connections[connectionId] = new UserConnection
            {
                ConnectionId = connectionId,
                UserId = userId,
                UserRole = userRole,
                Department = department,
                ConnectedAt = DateTime.UtcNow
            };

            // 加入用户组
            if (!string.IsNullOrEmpty(userRole))
            {
                await Groups.AddToGroupAsync(connectionId, $"Role_{userRole}");
            }
            
            if (!string.IsNullOrEmpty(department))
            {
                await Groups.AddToGroupAsync(connectionId, $"Dept_{department}");
            }

            // 发送欢迎消息
            await Clients.Caller.SendAsync("Connected", new
            {
                Message = "连接成功",
                ConnectionId = connectionId,
                ServerTime = DateTime.UtcNow
            });

            await base.OnConnectedAsync();
        }

        /// <summary>
        /// 客户端断开连接时调用
        /// </summary>
        public override async Task OnDisconnectedAsync(Exception? exception)
        {
            var connectionId = Context.ConnectionId;
            
            if (_connections.TryRemove(connectionId, out var connection))
            {
                _logger.LogInformation("用户断开连接: {UserId}, 连接ID: {ConnectionId}", 
                    connection.UserId, connectionId);
            }

            if (exception != null)
            {
                _logger.LogError(exception, "连接异常断开: {ConnectionId}", connectionId);
            }

            await base.OnDisconnectedAsync(exception);
        }

        #endregion

        #region AI助手实时对话

        /// <summary>
        /// 发送消息给AI助手
        /// </summary>
        /// <param name="message">用户消息</param>
        /// <param name="sessionId">会话ID</param>
        [HubMethodName("SendMessageToAI")]
        public async Task SendMessageToAIAsync(string message, string? sessionId = null)
        {
            try
            {
                var userId = GetUserId();
                _logger.LogInformation("收到AI对话请求: {UserId}, 消息: {Message}", userId, message);

                // 通知客户端开始处理
                await Clients.Caller.SendAsync("AIProcessingStarted", new
                {
                    Message = "AI正在思考中...",
                    Timestamp = DateTime.UtcNow
                });

                // 调用MES工具服务处理消息
                var result = await _mesToolService.QueryProductionOrdersAsync(new Dictionary<string, object>
                {
                    ["query"] = message,
                    ["userId"] = userId
                });

                // 发送AI回复
                await Clients.Caller.SendAsync("AIResponse", new
                {
                    Message = "基于您的查询，我找到了相关信息...",
                    Data = result,
                    SessionId = sessionId ?? Guid.NewGuid().ToString(),
                    Timestamp = DateTime.UtcNow
                });

                _logger.LogInformation("AI对话处理完成: {UserId}", userId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "AI对话处理失败");
                await Clients.Caller.SendAsync("AIError", new
                {
                    Message = "AI处理失败，请稍后重试",
                    Error = ex.Message,
                    Timestamp = DateTime.UtcNow
                });
            }
        }

        #endregion

        #region 生产状态推送

        /// <summary>
        /// 订阅生产订单状态更新
        /// </summary>
        /// <param name="orderIds">订单ID列表</param>
        [HubMethodName("SubscribeOrderStatus")]
        public async Task SubscribeOrderStatusAsync(List<string> orderIds)
        {
            var userId = GetUserId();
            var connectionId = Context.ConnectionId;

            foreach (var orderId in orderIds)
            {
                await Groups.AddToGroupAsync(connectionId, $"Order_{orderId}");
            }

            _logger.LogInformation("用户 {UserId} 订阅了 {Count} 个订单状态", userId, orderIds.Count);
            
            await Clients.Caller.SendAsync("SubscriptionConfirmed", new
            {
                OrderIds = orderIds,
                Message = "订阅成功"
            });
        }

        /// <summary>
        /// 取消订阅生产订单状态
        /// </summary>
        /// <param name="orderIds">订单ID列表</param>
        [HubMethodName("UnsubscribeOrderStatus")]
        public async Task UnsubscribeOrderStatusAsync(List<string> orderIds)
        {
            var connectionId = Context.ConnectionId;

            foreach (var orderId in orderIds)
            {
                await Groups.RemoveFromGroupAsync(connectionId, $"Order_{orderId}");
            }

            await Clients.Caller.SendAsync("UnsubscriptionConfirmed", new
            {
                OrderIds = orderIds,
                Message = "取消订阅成功"
            });
        }

        #endregion

        #region 设备监控

        /// <summary>
        /// 订阅设备状态监控
        /// </summary>
        /// <param name="equipmentCodes">设备编码列表</param>
        [HubMethodName("SubscribeEquipmentStatus")]
        public async Task SubscribeEquipmentStatusAsync(List<string> equipmentCodes)
        {
            var connectionId = Context.ConnectionId;

            foreach (var code in equipmentCodes)
            {
                await Groups.AddToGroupAsync(connectionId, $"Equipment_{code}");
            }

            await Clients.Caller.SendAsync("EquipmentSubscriptionConfirmed", new
            {
                EquipmentCodes = equipmentCodes,
                Message = "设备监控订阅成功"
            });
        }

        #endregion

        #region 告警通知

        /// <summary>
        /// 订阅告警通知
        /// </summary>
        /// <param name="alertTypes">告警类型列表</param>
        [HubMethodName("SubscribeAlerts")]
        public async Task SubscribeAlertsAsync(List<string> alertTypes)
        {
            var connectionId = Context.ConnectionId;
            var userRole = GetUserRole();

            // 根据用户角色过滤可订阅的告警类型
            var allowedAlerts = FilterAlertsByRole(alertTypes, userRole);

            foreach (var alertType in allowedAlerts)
            {
                await Groups.AddToGroupAsync(connectionId, $"Alert_{alertType}");
            }

            await Clients.Caller.SendAsync("AlertSubscriptionConfirmed", new
            {
                AlertTypes = allowedAlerts,
                Message = "告警订阅成功"
            });
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 获取用户ID
        /// </summary>
        private string GetUserId()
        {
            return Context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? 
                   Context.User?.Identity?.Name ?? 
                   "anonymous";
        }

        /// <summary>
        /// 获取用户角色
        /// </summary>
        private string GetUserRole()
        {
            return Context.User?.FindFirst(ClaimTypes.Role)?.Value ?? "user";
        }

        /// <summary>
        /// 获取用户部门
        /// </summary>
        private string GetUserDepartment()
        {
            return Context.User?.FindFirst("department")?.Value ?? "default";
        }

        /// <summary>
        /// 根据角色过滤告警类型
        /// </summary>
        private List<string> FilterAlertsByRole(List<string> alertTypes, string userRole)
        {
            // 根据用户角色过滤告警类型
            return userRole.ToLower() switch
            {
                "admin" => alertTypes, // 管理员可以订阅所有告警
                "manager" => alertTypes.Where(a => !a.Contains("system")).ToList(),
                "operator" => alertTypes.Where(a => a.Contains("production")).ToList(),
                _ => new List<string>()
            };
        }

        #endregion
    }

    /// <summary>
    /// 用户连接信息
    /// </summary>
    public class UserConnection
    {
        public string ConnectionId { get; set; } = string.Empty;
        public string UserId { get; set; } = string.Empty;
        public string UserRole { get; set; } = string.Empty;
        public string Department { get; set; } = string.Empty;
        public DateTime ConnectedAt { get; set; }
    }
}
